﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;

namespace Homework_7th
{
    public partial class Form1 : Form
    {
        private Graphics graphics;//画图对象

        //使用类似队列的形式存储和访问各个边，便于控制程序进程，实现手动调整树
        private List<Edge> edges;//存储各个Edge类型的边
        private int head,rear;//头尾指针

        //树的层数
        private int depth;
        public Form1()
        {
            edges = new List<Edge>();
            head = -1;
            rear = 0;
            InitializeComponent();
            ComboBoxColor.Items.Clear();
            ComboBoxColor.Items.Add("Red");
            ComboBoxColor.Items.Add("Green");
            ComboBoxColor.Items.Add("Blue");
            ComboBoxColor.Items.Add("Yellow");
            ComboBoxColor.Items.Add("Pink");
            ComboBoxColor.Items.Add("Purple");
            ComboBoxColor.Items.Add("Black");
            depth = 8;
            TextBoxDepth.Text = "8";
            TextBoxHeight.Text = "200";
            TextBoxLLength.Text = "0.8";
            TextBoxLAngle.Text = "30";
            TextBoxRLength.Text = "0.6";
            TextBoxRAngle.Text = "20";
            ComboBoxColor.Text = "Green";
        }

        /// <summary>
        /// 确定按钮，
        /// 画出本层的树枝，
        /// 并计算下一层树枝的各项属性，调用相关方法加入下一层树枝
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ButtonConFirm_Click(object sender, EventArgs e)
        {
            try
            {
                depth = int.Parse(TextBoxDepth.Text);
            }
            catch (FormatException)
            {
                return;
            }
            if (edges.Count == 0)
            {
                edges.Add(new Edge(
                    600,600,600,600-int.Parse(TextBoxHeight.Text),0,true
                    ));
                rear++;
            }
            int pause = rear - 1;
            while (head < pause && depth > 0) 
            {
                head++;
                DrawBranch(edges[head].x1, edges[head].y1, edges[head].x2, edges[head].y2, ComboBoxColor.Text);
                int angleL = 0, angleR = 0;
                if (edges[head].isLeft)
                {
                    angleL = edges[head].angle - int.Parse(TextBoxLAngle.Text);
                    angleR = edges[head].angle + int.Parse(TextBoxRAngle.Text);
                }
                else if (!edges[head].isLeft)
                {
                    angleL = edges[head].angle + int.Parse(TextBoxLAngle.Text);
                    angleR = edges[head].angle - int.Parse(TextBoxRAngle.Text);
                }

                double lengthL = edges[head].length * Convert.ToDouble(TextBoxLLength.Text);
                double lengthR = edges[head].length * Convert.ToDouble(TextBoxRLength.Text);
                AddChildEdgesOf_head(edges[head].x2, edges[head].y2, angleL, (int)lengthL);
                AddChildEdgesOf_head(edges[head].x2, edges[head].y2, angleR, (int)lengthR);
            }
            depth--;
            if (depth <= 0)
                TextBoxDepth.Text = "停止生长";
            else
                TextBoxDepth.Text = depth.ToString();
        }

        /// <summary>
        /// 砍树按钮，将会清空屏幕，清理树枝容器，
        /// 并更新相关属性
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            graphics.Clear(this.BackColor);
            depth = 8;
            TextBoxDepth.Text = "8";
            TextBoxHeight.Text = "200";
            TextBoxLLength.Text = "0.8";
            TextBoxLAngle.Text = "30";
            TextBoxRLength.Text = "0.5";
            TextBoxRAngle.Text = "20";
            ComboBoxColor.Text = "Green";
            edges.Clear();
            head = -1;
            rear = 0;
        }

        /// <summary>
        /// 被确认按钮调用的使用数学方法向容器中加入树枝的方法
        /// </summary>
        /// <param name="x1"></param>
        /// <param name="y1"></param>
        /// <param name="angle"></param>
        /// <param name="length"></param>
        private void AddChildEdgesOf_head(int x1, int y1, int angle, int length)
        {
            double newX2 = x1, newY2 = y1;
            double alpha = angle * Math.PI / 180;
            newY2 = y1 - length * Math.Cos(alpha);
            newX2 = x1 + length * Math.Sin(alpha);
            edges.Add(new Edge(x1, y1, (int)newX2, (int)newY2, angle,true));
            rear++;
        }

        /// <summary>
        /// 画出一个树枝分支的方法
        /// </summary>
        /// <param name="x1"></param>
        /// <param name="y1"></param>
        /// <param name="x2"></param>
        /// <param name="y2"></param>
        /// <param name="color"></param>
        private void DrawBranch(int x1, int y1, int x2, int y2,String color)
        {
            if (graphics == null)
                graphics = this.CreateGraphics();
            switch (color)
            {
                case "Red": 
                    graphics.DrawLine(Pens.Red, x1, y1, x2, y2);
                    break;
                case "Green":
                    graphics.DrawLine(Pens.Green, x1, y1, x2, y2);
                    break;
                case "Blue":
                    graphics.DrawLine(Pens.Blue, x1, y1, x2, y2);
                    break;
                case "Yellow":
                    graphics.DrawLine(Pens.Yellow, x1, y1, x2, y2);
                    break;
                case "Black":
                    graphics.DrawLine(Pens.Black, x1, y1, x2, y2);
                    break;
                case "Pink":
                    graphics.DrawLine(Pens.Pink, x1, y1, x2, y2);
                    break;
                case "Purple":
                    graphics.DrawLine(Pens.Purple, x1, y1, x2, y2);
                    break;
            }
        }
    }
}
